package com.luohoufa.ms.order.controller;

import com.netflix.hystrix.contrib.javanica.annotation.DefaultProperties;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import java.util.Arrays;

@RestController
@RequestMapping("/order")
@DefaultProperties(defaultFallback = "defaultFallback")
public class HystrixController {

    /**
     * 没有设置fallbackMethod，则使用defaultFallback
     * @HystrixCommand//(fallbackMethod = "fallbackGetProductInfoList")
     */
    // 超时设置
//    @HystrixCommand(fallbackMethod = "fallbackGetProductInfoList", commandProperties = {
//            @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "2000")
//    })
    // 服务熔断设置
    @HystrixCommand(commandProperties = {
            @HystrixProperty(name = "circuitBreaker.enabled", value = "true"),// 设置熔断
            /**
             * 意思是至少有20个请求才进行errorThresholdPercentage错误百分比计算。
             * 比如一段时间（10s）内有19个请求全部失败了。错误百分比是100%，但熔断器不会打开，
             * 因为requestVolumeThreshold的值是20.
             * 这个参数非常重要，熔断器是否打开首先要满足这个条件.
             */
            @HystrixProperty(name = "circuitBreaker.requestVolumeThreshold", value = "10"),//断路器的最少请求数
            @HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds", value = "10000"),//半开试探休眠时间（当熔断开启一断时间后，会尝试放过去一部分流量进行试探，确定依赖服务是否恢复）
            @HystrixProperty(name = "circuitBreaker.errorThresholdPercentage", value = "60")//错误百分比（例如一段时间（10s）内有100个请求，其中有55个超时或者异常返回了，那么这段时间内的错误百分比是55%，大于了默认值50%，这种情况下触发熔断器-打开）
    })
    @GetMapping("/getProductInfoList")
    public String getProductInfoList(@RequestParam("number") Integer number) {
        // 1. product服务异常时，可以触发降级
        if (number == null) {
            return "success";
        }
        RestTemplate restTemplate = new RestTemplate();
        return restTemplate.postForObject("http://localhost:8772/product/listForOrder",
                Arrays.asList("164103465734242707"), String.class);
        //return new RuntimeException("发生异常了")//2. 服务内部异常时可以触发降级
    }

    private String fallbackGetProductInfoList() {
        return "太拥挤了，请稍候再试~~";
    }

    private String defaultFallback() {
        return "默认提示，太拥挤了，请稍候再试~~";
    }

}
